package ewms.service.impl;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ewms.common.constant.UserConstants;
import ewms.common.core.domain.TreeSelect;
import ewms.common.exception.CustomException;
import ewms.domain.EwmsWasteType;
import ewms.domain.EwmsWasteTypeTreeSelect;
import ewms.mapper.EwmsWasteTypeMapper;
import ewms.service.IEwmsWasteTypeService;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 废弃物类别管理 服务实现
 *
 * @author ruoyi
 */
@Service
public class EwmsWasteTypeServiceImpl extends ServiceImpl<EwmsWasteTypeMapper, EwmsWasteType> implements IEwmsWasteTypeService {

	private Map<Long, List<EwmsWasteType>> wasteDetailMap = new HashMap();

	/**
	 * 查询危废分类管理数据
	 *
	 * @param wasteType 危废分类信息
	 * @return 危废分类信息集合
	 */
	@Override
	public List<EwmsWasteType> selectWasteTypeList(EwmsWasteType wasteType) {
		return baseMapper.selectWasteTypeList(wasteType);
	}

	/**
	 * 查询危废分类管理数据
	 *
	 * @return 危废分类信息集合
	 */
	@Override
	public List<EwmsWasteType> selectAllWasteList() {
		List<EwmsWasteType> wasteTypeList = baseMapper.selectWasteTypeList(new EwmsWasteType());
		wasteDetailMap.clear();
		baseMapper.selectWasteDetailList().stream()
			.forEach(item -> {
				item.setIsWasteType(false);
				item.setWasteTypeId(0 - item.getWasteTypeId());
			List<EwmsWasteType> typeList = wasteDetailMap.get(item.getParentId());
			if (typeList == null){
				typeList = new ArrayList<>();
			}
				typeList.add(item);
				wasteDetailMap.put(item.getParentId(), typeList);
			});
		List<EwmsWasteType> treeWasteTypeList = this.buildWasteTypeTree(wasteTypeList);
		this.allRecursionFn(treeWasteTypeList);
		return wasteTypeList;
	}

	/**
	 * 递归列表
	 */
	private void allRecursionFn(List<EwmsWasteType> list) {
		for (EwmsWasteType tChild : list) {
			if (Validator.isNotNull(tChild.getParentId()) && wasteDetailMap.containsKey(tChild.getWasteTypeId()) ){
				tChild.setChildren(wasteDetailMap.get(tChild.getWasteTypeId()));
			}
			if (tChild.getChildren().size()>0) {
				allRecursionFn(tChild.getChildren());
			}else if(tChild.getIsWasteType()){
				tChild.setDisabled(true);
			}
		}
	}

	/**
	 * 构建前端所需要树结构
	 *
	 * @param ewmsWasteTypeList 废弃物类别列表
	 * @return 树结构列表
	 */
	@Override
	public List<EwmsWasteType> buildWasteTypeTree(List<EwmsWasteType> ewmsWasteTypeList) {
		List<EwmsWasteType> returnList = new ArrayList<EwmsWasteType>();
		List<Long> tempList = new ArrayList<Long>();
		for (EwmsWasteType wasteType : ewmsWasteTypeList) {
			tempList.add(wasteType.getWasteTypeId());
		}
		for (Iterator<EwmsWasteType> iterator = ewmsWasteTypeList.iterator(); iterator.hasNext(); ) {
			EwmsWasteType wasteType = (EwmsWasteType) iterator.next();
			// 如果是顶级节点, 遍历该父节点的所有子节点
			if (!tempList.contains(wasteType.getParentId())) {
				this.recursionFn(ewmsWasteTypeList, wasteType);
				returnList.add(wasteType);
			}
		}
		if (returnList.isEmpty()) {
			returnList = ewmsWasteTypeList;
		}
		return returnList;
	}

	/**
	 * 构建前端所需要下拉树结构
	 *
	 * @param wasteTypeList 废弃物分类列表
	 * @return 下拉树结构列表
	 */
	@Override
	public List<TreeSelect> buildWasteTypeTreeSelect(List<EwmsWasteType> wasteTypeList) {
		List<EwmsWasteType> retWasteTypeList = buildWasteTypeTree(wasteTypeList);
		return retWasteTypeList.stream().map(EwmsWasteTypeTreeSelect::new).collect(Collectors.toList());
	}

	/**
	 * 根据危废分类ID查询信息
	 *
	 * @param wasteTypeId 危废分类ID
	 * @return 危废分类信息
	 */
	@Override
	public EwmsWasteType selectWasteTypeById(Long wasteTypeId) {
		return getById(wasteTypeId);
	}

	/**
	 * 根据ID查询所有子危废分类（正常状态）
	 *
	 * @param wasteTypeId 危废分类ID
	 * @return 子危废分类数
	 */
	@Override
	public int selectNormalChildrenWasteTypeById(Long wasteTypeId) {
		return count(new LambdaQueryWrapper<EwmsWasteType>()
			.eq(EwmsWasteType::getStatus, 0)
			.apply("find_in_set({0}, ancestors)", wasteTypeId));
	}

	/**
	 * 是否存在子节点
	 *
	 * @param wasteTypeId 危废分类ID
	 * @return 结果
	 */
	@Override
	public boolean hasChildByWasteTypeId(Long wasteTypeId) {
		int result = count(new LambdaQueryWrapper<EwmsWasteType>()
			.eq(EwmsWasteType::getParentId, wasteTypeId)
			.last("limit 1"));
		return result > 0 ? true : false;
	}

	/**
	 * 校验废弃物分类名称是否唯一
	 *
	 * @param wasteType 危废分类信息
	 * @return 结果
	 */
	@Override
	public String checkWasteTypeNameUnique(EwmsWasteType wasteType) {
		Long deptId = Validator.isNull(wasteType.getWasteTypeId()) ? -1L : wasteType.getWasteTypeId();
		EwmsWasteType info = getOne(new LambdaQueryWrapper<EwmsWasteType>()
			.eq(EwmsWasteType::getWasteTypeName, wasteType.getWasteTypeName())
			.eq(EwmsWasteType::getParentId, wasteType.getParentId())
			.last("limit 1"));
		if (Validator.isNotNull(info) && info.getWasteTypeId().longValue() != deptId.longValue()) {
			return UserConstants.NOT_UNIQUE;
		}
		return UserConstants.UNIQUE;
	}

	/**
	 * 新增保存危废分类信息
	 *
	 * @param wasteType 危废分类信息
	 * @return 结果
	 */
	@Override
	public int insertWasteType(EwmsWasteType wasteType) {
		EwmsWasteType info = getById(wasteType.getParentId());
		// 如果父节点不为正常状态,则不允许新增子节点
		if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) {
			throw new CustomException("危废分类停用，不允许新增");
		}
		wasteType.setAncestors(info.getAncestors() + "," + wasteType.getParentId());
		return baseMapper.insert(wasteType);
	}

	/**
	 * 修改保存危废分类信息
	 *
	 * @param wasteType 危废分类信息
	 * @return 结果
	 */
	@Override
	public int updateWasteType(EwmsWasteType wasteType) {
		EwmsWasteType newParentDept = getById(wasteType.getParentId());
		EwmsWasteType oldDept = getById(wasteType.getWasteTypeId());
		if (Validator.isNotNull(newParentDept) && Validator.isNotNull(oldDept)) {
			String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getWasteTypeId();
			String oldAncestors = oldDept.getAncestors();
			wasteType.setAncestors(newAncestors);
			updateDeptChildren(wasteType.getWasteTypeId(), newAncestors, oldAncestors);
		}
		int result = baseMapper.updateById(wasteType);
		if (UserConstants.DEPT_NORMAL.equals(wasteType.getStatus())) {
			// 如果该危废分类是启用状态，则启用该废弃物分类的所有上级分类
			updateParentDeptStatus(wasteType);
		}
		return result;
	}

	/**
	 * 修改该危废分类的父级分类状态
	 *
	 * @param wasteType 废弃物分类
	 */
	private void updateParentDeptStatus(EwmsWasteType wasteType) {
		String updateBy = wasteType.getUpdateBy();
		wasteType = getById(wasteType.getWasteTypeId());
		wasteType.setUpdateBy(updateBy);
		update(null, new LambdaUpdateWrapper<EwmsWasteType>()
			.set(StrUtil.isNotBlank(wasteType.getStatus()),
				EwmsWasteType::getStatus, wasteType.getStatus())
			.set(StrUtil.isNotBlank(wasteType.getUpdateBy()),
				EwmsWasteType::getUpdateBy, wasteType.getUpdateBy())
			.in(EwmsWasteType::getWasteTypeId, Arrays.asList(wasteType.getAncestors().split(","))));
	}

	/**
	 * 修改子元素关系
	 *
	 * @param deptId       被修改的危废分类ID
	 * @param newAncestors 新的父ID集合
	 * @param oldAncestors 旧的父ID集合
	 */
	public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) {
		List<EwmsWasteType> children = list(new LambdaQueryWrapper<EwmsWasteType>()
			.apply("find_in_set({0},ancestors)", deptId));
		for (EwmsWasteType child : children) {
			child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
		}
		if (children.size() > 0) {
			baseMapper.updateWasteTypeChildren(children);
		}
	}

	/**
	 * 删除危废分类管理信息
	 *
	 * @param wasteTypeId 危废分类ID
	 * @return 结果
	 */
	@Override
	public int deleteWasteTypeById(Long wasteTypeId) {
		return baseMapper.deleteById(wasteTypeId);
	}

	/**
	 * 递归列表
	 */
	private void recursionFn(List<EwmsWasteType> list, EwmsWasteType t) {
		// 得到子节点列表
		List<EwmsWasteType> childList = getChildList(list, t);
		t.setChildren(childList);
		for (EwmsWasteType tChild : childList) {
			if (hasChild(list, tChild)) {
				recursionFn(list, tChild);
			}
		}
	}

	/**
	 * 得到子节点列表
	 */
	private List<EwmsWasteType> getChildList(List<EwmsWasteType> list, EwmsWasteType t) {
		List<EwmsWasteType> tlist = new ArrayList<EwmsWasteType>();
		Iterator<EwmsWasteType> it = list.iterator();
		while (it.hasNext()) {
			EwmsWasteType n = (EwmsWasteType) it.next();
			if (Validator.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getWasteTypeId().longValue() && n.getIsWasteType()) {
				tlist.add(n);
			}
		}
		return tlist;
	}

	/**
	 * 判断是否有子节点
	 */
	private boolean hasChild(List<EwmsWasteType> list, EwmsWasteType t) {
		return getChildList(list, t).size() > 0 ? true : false;
	}
}
